package com.arpa.ntocc.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.AreaCache;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.dto.ShipmentDTO;
import com.arpa.ntocc.common.domain.dto.ShipmentFromDTO;
import com.arpa.ntocc.common.domain.entity.Shipment;
import com.arpa.ntocc.common.domain.vo.ShipmentVO;
import com.arpa.ntocc.common.mapper.ShipmentMapper;
import com.arpa.ntocc.common.service.IShipmentService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 货主表 服务实现类
 * </p>
 *
 * @author liuyj
 * @since 2019-11-27
 */
@Service
@Log4j2
public class ShipmentServiceImpl extends ServiceImpl<ShipmentMapper, Shipment> implements IShipmentService {
    @Autowired
    private ShipmentCache shipmentCache;
    @Autowired
    private PartyCache partyCache;
    @Autowired
    private AreaCache areaCache;


    /**
     * 添加入驻商
     *
     * @param entity
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(ShipmentFromDTO entity) {
        Shipment shipment = getOne(new QueryWrapper<Shipment>().lambda()
                .eq(Shipment::getPartyCode, entity.getPartyCode()).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
        if (ObjectUtil.isNotNull(shipment)) {
            throw new ServiceException("该入驻商编码已存在！");
        }
        List<String> areaList = entity.getAreaList();
        // TODO 为什么要判断size ！= 3
        if (areaList != null && areaList.size() == 3) {
            entity.setProvinceCode(areaList.get(0));
            entity.setCityCode(areaList.get(1));
            entity.setCountyCode(areaList.get(2));
        }
        shipment = new Shipment();
        BeanUtil.copyProperties(entity, shipment);
        shipment.setBranchCode(UserUtil.getBranchCode());

        shipment.setCreatedBy(UserUtil.getCode());
        shipment.setCreatedName(partyCache.translate(UserUtil.getCode()));

        shipment.setModifiedBy(UserUtil.getCode());
        shipment.setModifiedName(partyCache.translate(UserUtil.getCode()));

        shipment.setCode(IdUtil.simpleUUID());
        shipment.setAuthStatus(0);
        super.save(shipment);
    }


    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    public int updateByCode(Shipment entity) {
        if (StringUtils.isBlank(entity.getModifiedBy())) {
            entity.setModifiedBy(UserUtil.getCode());
        }
        return baseMapper.update(entity, new QueryWrapper<Shipment>().lambda().eq(Shipment::getCode, entity.getCode()).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
    }

    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByCode(ShipmentFromDTO entity) {
        //入驻商状态为审核未通过时，更新状态为待审核
        if (2 == entity.getAuthStatus()) {
            entity.setAuthStatus(0);
        }
        Shipment shipment = getOne(new QueryWrapper<Shipment>().lambda().eq(Shipment::getCode, entity.getCode()).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
        if (shipment == null) {
            log.info("修改货主失败：货主信息【{}】找不到", entity.getCode());
            throw new ServiceException("找不到货主信息！");
        }

        List<String> areaList = entity.getAreaList();
        // TODO 为什么要判断size != 3
        if (areaList != null && areaList.size() == 3) {
            entity.setProvinceCode(areaList.get(0));
            entity.setCityCode(areaList.get(1));
            entity.setCountyCode(areaList.get(2));
        }
        shipment = new Shipment();
        BeanUtil.copyProperties(entity, shipment);
        shipment.setModifiedName(partyCache.translate(UserUtil.getCode()));

        shipmentCache.flushCache(shipment.getPartyCode());
        return updateByCode(shipment);
    }


    /**
     * 查询列表
     *
     * @param shipmentDTO
     * @return
     */
    @Override
    public List<ShipmentVO> queryList(ShipmentDTO shipmentDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(shipmentDTO.getSortField())) {
            shipmentDTO.setSortField(CommonUtil.camel2Underline(shipmentDTO.getSortField()));
        }
        List<ShipmentVO> shipmentVOList = baseMapper.queryList(shipmentDTO);
        return shipmentVOList;
    }

    /**
     * 查询合计,包含总数
     *
     * @param shipmentDTO
     * @return
     */
    @Override
    public ShipmentVO queryListSum(ShipmentDTO shipmentDTO) {
        ShipmentVO shipmentVO = baseMapper.queryListSum(shipmentDTO);
        return shipmentVO;
    }

    /**
     * 根据入驻商编码查询入驻商
     */
    @Override
    public Shipment findShipmentByPartyCode(String partyCode) {
        return baseMapper.selectOne(new QueryWrapper<Shipment>().lambda().eq(Shipment::getPartyCode, partyCode).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
    }


    /**
     * 获取详情
     *
     * @param code
     * @return
     */
    @Override
    public ShipmentVO getOneInfo(String code) {
        Shipment shipment = baseMapper.selectOne(new QueryWrapper<Shipment>().lambda().eq(Shipment::getCode, code).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
        Optional.ofNullable(shipment).orElseThrow(() -> new ServiceException("没有查询到信息"));


        ShipmentVO entity = new ShipmentVO();
        BeanUtil.copyProperties(shipment, entity);
        if (StrUtil.isNotBlank(entity.getProvinceCode())) {
            entity.setProvinceName(areaCache.translateProvince(entity.getProvinceCode()));
        }
        if (StrUtil.isNotBlank(entity.getCityCode())) {
            entity.setCityName(areaCache.translateProvince(entity.getCityCode()));
        }
        if (StrUtil.isNotBlank(entity.getCountyCode())) {
            entity.setCountyName(areaCache.translateProvince(entity.getCountyCode()));
        }
        return entity;
    }

    /**
     * 删除货主
     *
     * @param codes
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeShipment(List<String> codes) {
        //删除货主
        List<Shipment> shipmentList = baseMapper.selectList(new QueryWrapper<Shipment>().lambda().in(Shipment::getCode, codes).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
        if (CollectionUtils.isEmpty(shipmentList)) {
            throw new ServiceException("没有查询到要删除的信息");
        }
        shipmentList.stream().map(Shipment::getPartyCode).forEach(c -> shipmentCache.flushCache(c));
        baseMapper.delete(new QueryWrapper<Shipment>().lambda().in(Shipment::getCode, codes));

    }




    /**
     * 根据 货主编码 获取 数据
     *
     * @param serialNumber
     * @return
     */
    @Override
    public Shipment shipmentBySerial(String serialNumber) {
        return getOne(new QueryWrapper<Shipment>().lambda().eq(Shipment::getPartyCode, serialNumber).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
    }


    /**
     * 根据 货主名称 获取 数据
     *
     * @param
     * @return
     */
    @Override
    public Shipment shipmentBySerialName(String name) {
        return getOne(new QueryWrapper<Shipment>().lambda().eq(Shipment::getUserName, name).eq(Shipment::getBranchCode,UserUtil.getBranchCode()));
    }

    /**
     * 判断货主是否需要复核
     *
     * @param shipmentCodes
     */
    @Override
    public Result judgeRecheck(List<String> shipmentCodes){
        //选中多个订单时，如果都是复核出库，则返回（是）复核出库，否则返回（否）复核出库
        List<Shipment> shipmentList = this.list(new LambdaQueryWrapper<Shipment>().in(Shipment::getPartyCode, shipmentCodes));
        List<Shipment> shipmentNeedRecheckList = shipmentList.stream().filter(e -> 1 == e.getReview()).collect(Collectors.toList());
        ShipmentVO shipmentVO = new ShipmentVO();
        shipmentVO.setReview(0);
        if (shipmentList.size() == shipmentNeedRecheckList.size()) {
            shipmentVO.setReview(1);
        }
        return Result.ok().data(shipmentVO);
    }


}
